package cn.antcore.common.authentication.serialize;

import cn.antcore.common.user.AuthUserDetails;
import cn.antcore.common.user.UserGrantedAuthority;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.MissingNode;
import org.springframework.security.core.GrantedAuthority;

import java.io.IOException;
import java.util.List;

/**
 * 自定义AuthUserDetails反序列化
 * <br>
 * Created by Hong 2024/5/28
**/
public class AuthUserDetailsDeserializer extends JsonDeserializer<AuthUserDetails> {

    @Override
    public AuthUserDetails deserialize(JsonParser jp, DeserializationContext deserializationContext) throws IOException, JacksonException {
        ObjectMapper mapper = (ObjectMapper) jp.getCodec();
        JsonNode jsonNode = mapper.readTree(jp);
        List<? extends GrantedAuthority> authorities = mapper.convertValue(jsonNode.get("authorities"), new TypeReference<>() {
        });
        String username = readJsonNode(jsonNode, "username").asText();
        String mobile = readJsonNode(jsonNode, "mobile").asText();
        String password = readJsonNode(jsonNode, "password").asText("");
        boolean enabled = readJsonNode(jsonNode, "enabled").asBoolean();
        boolean accountNonExpired = readJsonNode(jsonNode, "accountNonExpired").asBoolean();
        boolean credentialsNonExpired = readJsonNode(jsonNode, "credentialsNonExpired").asBoolean();
        boolean accountNonLocked = readJsonNode(jsonNode, "accountNonLocked").asBoolean();
        AuthUserDetails result = new AuthUserDetails(username, password, authorities);
        result.setEnabled(enabled);
        result.setMobile(mobile);
        result.setAccountNonExpired(accountNonExpired);
        result.setCredentialsNonExpired(credentialsNonExpired);
        result.setAccountNonLocked(accountNonLocked);
        return result;
    }

    private JsonNode readJsonNode(JsonNode jsonNode, String field) {
        return jsonNode.has(field) ? jsonNode.get(field) : MissingNode.getInstance();
    }
}
